// 玩家角色表
package db
import (
	"time"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"github.com/name5566/leaf/log"
	"github.com/name5566/leaf/util"
	"config"
)

const (
	TBL_USER = "tbl_user"    // 表名
	TBL_USER_INDEX = "account"    // 索引字段名
)

// 玩家的数据结构，对应数据库中的tbl_user表
type UserData struct {
	EntityID   bson.ObjectId  `bson:"_id"`
	UserID     int            `bson:"user_id"`  // 玩家id 实际游戏中通过这个id识别玩家（尤其是跟客户端交互的时候），这是一个自增的id
	Account    string        `bson:"account"`   // 账户名，如果是第三方登录则为第三方id，如果是默认登录则为udid
	Name       string        `bson:"name"`      // 玩家名字
	Icon       string `bson:"icon"`             // 玩家头像
	TotalMoney int64    `bson:"total_money"`    // 总金钱
	TotalCount int32    `bson:"total_count"`    // 总比赛场数
	WinCount   int32        `bson:"win_count"`  // 胜利的场数
	CreateTime int64    `bson:"create_time"`    // 注册时间
	LoginTime  int64        `bson:"login_time"` // 上次登录时间
}

// 先用同步的方式，将来修改为异步的
func FindUser(account string) *UserData {
	session := DB.Ref()
	defer DB.UnRef(session)

	// 玩家对象
	userData := new(UserData)

	err := session.DB(config.DB_NAME).C(TBL_USER).Find(bson.M{"account": account}).One(userData)
	if err != nil {
		return nil
	}

	return userData
}

// 创建一个新的玩家
func CreateUser(account string) *UserData {
	session := DB.Ref()
	defer DB.UnRef(session)

	// 玩家对象
	userData := new(UserData)
	collection := session.DB(config.DB_NAME).C(TBL_USER)
	err := collection.Find(bson.M{"account": account}).One(userData)

	if err != nil {
		if err == mgo.ErrNotFound {
			userData.EntityID = bson.NewObjectId()
			userData.Account = account
			userData.CreateTime = time.Now().Unix()
			userData.TotalCount = 0
			userData.WinCount = 0
			userData.TotalMoney = config.INIT_TOTAL_MONEY
			userData.UserID, _ = DBNextSeq(TBL_USER)

			err := collection.Insert(userData)
			if err != nil {
				log.Error("InsertUser Error:  %s  %v", account, err)
				return nil
			}

			return userData
		} else {
			log.Error("CreateUser Error:  %s  %v", account, err)
		}
	} else {
		// 正确的查找到的玩家，则此玩家已经存在，不能创建
		log.Error("CreateUser Error, User Exist:  %s  %s", account, err)
	}

	return nil
}

// 加载所有的玩家
func LoadAllUsers() []UserData {
	session := DB.Ref()
	defer DB.UnRef(session)

	// 玩家对象
	var users []UserData
	err := session.DB(config.DB_NAME).C(TBL_USER).Find(nil).All(users)
	if err != nil {
		log.Error("LoadAllUsers error: %v", err)
		return nil
	}

	return users
}

// 将玩家数据存储到数据库中
func SaveUser(userData *UserData) {
	data := util.DeepClone(userData)
	session := DB.Ref()
	defer DB.UnRef(session)
	entityID := data.(*UserData).EntityID
	_, err := session.DB(config.DB_NAME).C(TBL_USER).UpsertId(entityID, data)
	if err != nil {
		log.Error("save user %v data error: %v", entityID, err)
	}
}